package robocup.component.tactics;

import robocup.component.SConf;
import robocup.component.ControllerNumbers.PLAY_MODE;
import robocup.component.actionfactories.TurnNeckActionFactory;
import robocup.component.actions.TurnNeckAction;

public class DribbleState
    extends AbstractState {

  /**
   * State which causes the Player to Dribble
   */
  public DribbleState(
      final StateEvaluation parent) {

    super(parent);
    this.state = STATES.DRIBBLE;
  }

  /**
   * Precondition is set up by player has ball, defined in AbstractState.
   */
  @Override
  public boolean preCondition() {

    if (!this.checkPlayMode()) {
      return false;
    }

    if ((this.getWorld().getNumber() == 10) && PLAY_MODE.META_PENALTY_OWN
        .contains(this.getWorld().getPlayMode())) {
      if (this.getWorld().canKick()) {
        return true;
      }
      else {
        return false;
      }
    }

    if (PLAY_MODE.META_PENALTY_OWN.contains(this.getWorld().getPlayMode())) {
      return false;
    }

    final boolean b = (this.checkPlayMode() && this.getWorld().canKick() && this
        .checkMyBall() && (this.getProphet().getScoreBenefit() < 0.80));

    // if(b || checkPlayerHasBall()){
    // System.out.println(this.getWorld().getCycleAndPlayerString() +
    // "DribbleState " + b + this.getProphet().isClearBallSituation());
    // }
    // if (getWorld().getNumber() == 10)
    // System.out.println(getWorld().getCycleAndPlayerString()
    // + " [Dribble] " + b);

    return b;
  }

  /**
   * The success of dribbling depends on the distance of other players to the
   * ball. In particular, if the ball is inside their kickable margin, the
   * success probability is lowest. If this is not the case, dribbling is more
   * successfully.
   */
  @Override
  protected double successProbability() {

    return 1.0;
  }

  /**
   * This method calcultes the estimated benefit when dribbling. The estimate
   * depends on the distance to the other goal, nearer is better.
   */
  @Override
  protected double successBenefit() {

    final double ben = this.getProphet().getDribbleBenefit();
    if (this.getWorld().inOpponentsPenalty(this.getWorld().getSelfRef())) {
      return (ben / 1.2);
    }
    if (this.getWorld().inOwnPenaltyArea(this.getWorld().getSelfRef())) {
      return (ben / 1.2);
    }
    return ben;
  }

  @Override
  public void calculateMainAction() {

    this.subStateString = this.empty;
    this.mainAction = this.getProphet().getBestDribbleAction();
  }

  /*
   * (non-Javadoc)
   * 
   * @see robocup.component.tactics.AbstractState#setSubStateString()
   */
  @Override
  public void setSubStateString() {

    this.subStateString = this.getProphet().getDribbleSituationSubstateString();
  }

  /*
   * (non-Javadoc)
   * 
   * @see robocup.component.tactics.AbstractState#calculateTurnNeckAction()
   */
  @Override
  public void calculateTurnNeckAction() {

    // if (this.getProphet().shouldWatchGoalie()) {
    // this.turnNeckAction =
    // getProphet().getTurnNeckAction(STATES.WATCH_GOALIE_OTHER,
    // this.mainAction, this.viewModeAction);
    // }
    // else {
    if ((this.getWorld().getAgeOfPoint(SConf.getInstance().GOAL_POS_OTHER) > 1) && (this
        .getWorld().getOpponentsGoalie() != null) && (52.5 - this.getProphet()
        .getNextBallInterceptionPoint().getY() < 20)) {
      final TurnNeckAction tna = TurnNeckActionFactory.watchPoint(this
          .getWorld().getSelfRef(), SConf.getInstance().GOAL_POS_OTHER);
      if (tna != null) {
//        System.out.println(getWorld().getCycleAndPlayerString()+" watch goal: "+tna);
        this.turnNeckAction = tna;
        return;
      }
    }
    super.calculateTurnNeckAction();
    // }
  }

  /*
   * (non-Javadoc)
   * 
   * @see robocup.component.tactics.AbstractState#calculateAttentionToAction()
   */
  @Override
  public void calculateAttentionToAction() {

    // if (this.getProphet().shouldWatchGoalie()) {
    // this.attentionToAction = AttentionToActionFactory.getAction(this
    // .getWorld().getSelfRef(), STATES.WATCH_GOALIE_OTHER, this.getWorld(),
    // this.getProphet());
    // }
    // else {
    super.calculateAttentionToAction();
    // }
  }

}
